﻿using Application.Utils;
using Infrastructure.Utils;
using Infrastructure.WebApi;
using Infrastructure.WebApi.Middleware;
using IP2Region.Net.XDB;
using Medallion.Threading;
using Medallion.Threading.MySql;
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Rewrite;
using Microsoft.EntityFrameworkCore;
using Newtonsoft.Json;
using Serilog;
using Web;
using Web.Middlewares;

var builder = WebApplication.CreateBuilder(args);
var config = builder.Configuration;
var services = builder.Services;
// Add services to the container.
services.AddDbContext<JobManagerDbContext>(options =>
    options.UseMySql(config["MySql"], MySqlServerVersion.LatestSupportedServerVersion
));
services.AddSingleton<IDistributedLockProvider>(_ => new MySqlDistributedSynchronizationProvider(config["MySql"]));
services.AddControllers();
services.UseDatabaseMigration();
services.AddEndpointsApiExplorer();
services.AddQuartzInit();//添加系统任务
services.AddSwaggerWithAuth();
services.AddHealthChecks();

services.Configure<TokenOptions>(config.GetSection("TokenOptions")).AddSingleton<TokenBuilder>();
services.Configure<List<SysRole>>(config.GetSection("Roles"));//Roles
services.AddScopedServices();//注册服务到IOC
services.AddHttpClient();
services.Configure<ApiBehaviorOptions>(opts => opts.SuppressModelStateInvalidFilter = true);
services.AddSingleton<ISearcher, Searcher>();
services.AddHttpContextAccessor();

services.AddControllers(s =>
        {
            s.Filters.Add<AuthFilter>();
            s.Filters.Add<ModelBindFilter>();
            s.Filters.Add<OperationLogFilter>();
        }
        ).AddNewtonsoftJson(options =>
        {
            options.SerializerSettings.DateTimeZoneHandling = DateTimeZoneHandling.Local;//格式化为本地时间
            options.SerializerSettings.ReferenceLoopHandling = ReferenceLoopHandling.Ignore;//循环引用处理策略
            options.SerializerSettings.DateFormatString = "yyyy/MM/dd HH:mm:ss";//序列化或反序列化时，可接受的日期时间字符串格式
        });

var app = builder.Build();
Log.Logger = new LoggerConfiguration()
    .WriteTo.Console()
    .CreateLogger();
Log.Information("Starting web application");
app.UseHealthChecks("/health");

app.InitData();
// Configure the HTTP request pipeline.
app.UseMiddleware<ErrorHandlingMiddleware>();
if (app.Environment.IsDevelopment() || app.Environment.EnvironmentName == "Test")
{
    app.UseSwagger();
    app.UseSwaggerUI();
}


app.MapWhen(context =>
{
    return !context.Request.Path.Value.StartsWith("/api");
}, appBuilder =>
{
    appBuilder.UseStaticFiles();
    var option = new RewriteOptions();
    option.AddRewrite(".*", "/index.html", true);
    appBuilder.UseRewriter(option);
    appBuilder.UseStaticFiles();
});

app.UseCors(builder => builder
                   .SetIsOriginAllowed(host => true) //允许所有来源
                   .AllowAnyMethod() //允许任何请求方法(GET、POST、PUT、DELETE等)
                   .AllowAnyHeader() //允许任何请求头信息
                   .AllowCredentials() //允许跨域凭据
                   .SetPreflightMaxAge(TimeSpan.FromDays(30)) //指定可以缓存预检请求的响应的时间为30天
                   .WithExposedHeaders("X-Suggested-Filename", "set-user-token", "set-user"));
app.UseAuthorization();
app.MapControllers();
app.Run();
